using GamFi.Admin.API.Application.Exceptions;
using GamFi.Admin.API.Application.Interfaces;
using GamFi.Admin.API.Application.Resources;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;

namespace GamFi.Admin.API.Application.Features.Queries.User.UpdateUser;

/// <summary>
/// Обработчик команды на обновление информации о пользователе.
/// </summary>
public class UpdateUserCommandHandler : IRequestHandler<UpdateUserCommand, Unit>
{
    private readonly IDbContext _dbContext;
    private readonly IStringLocalizer<ExceptionMessages> _localizer;

    /// <summary>
    /// Конструктор обработчика команды на обновление информации о пользователе.
    /// </summary>
    /// <param name="dbContext">Контекст базы данных.</param>
    /// <param name="localizer">Локализатор исключений.</param>
    public UpdateUserCommandHandler(IDbContext dbContext, IStringLocalizer<ExceptionMessages> localizer)
    {
        _dbContext = dbContext;
        _localizer = localizer;
    }

    /// <summary>
    /// Обработка команды на обновление информации о пользователе.
    /// </summary>
    /// <param name="request">Команда на обновление информации о пользователе.</param>
    /// <param name="cancellationToken">Токен для отмены операции.</param>
    /// <returns>Результат выполнения команды.</returns>
    public async Task<Unit> Handle(UpdateUserCommand request, CancellationToken cancellationToken)
    {
        // Проверка на null-значение запроса
        if (request is null)
        {
            throw new RequestException(_localizer[nameof(RequestException.RequestIsEmpty)]);
        }

        // Получаем существующего пользователя
        var existingUser = await _dbContext.Users
            .Include(u => u.UserInfo) // Включаем связанную информацию о пользователе
            .FirstOrDefaultAsync(u => u.Id == request.UserId, cancellationToken);

        // Проверяем, найден ли пользователь
        if (existingUser is null)
            throw new UserException(_localizer[nameof(UserException.UserByIdNotFound)]);

        // Обновляем свойства пользователя
        existingUser.UserInfo.FirstName = request.FirstName;
        existingUser.UserInfo.LastName = request.LastName;
        existingUser.UserInfo.Patronymic = request.Patronymic;
        existingUser.UserInfo.CountryId = request.CountryId;
        existingUser.UserName = request.UserName;
        existingUser.UserInfo.ImageId = request.ImageId;

        // Сохраняем изменения в базе данных
        await _dbContext.SaveChangesAsync(cancellationToken);

        return Unit.Value;
    }
}